package com.net.xpay.admin.controller.admin;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.common.model.ResultPagedList;
import com.net.common.util.SerializationUtil;
import com.net.xpay.admin.vo.ChargeRecordExportVo;
import com.net.xpay.common.annotation.OperateLog;
import com.net.xpay.common.domain.UserShard;
import com.net.xpay.common.domain.sync.CommonChargeRecord;
import com.net.xpay.common.enums.config.FunctionModule;
import com.net.xpay.common.enums.config.MethodType;
import com.net.xpay.common.manager.UserShardManager;
import com.net.xpay.common.manager.sync.CommonChargeRecordManager;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.domain.ChargeRecord;
import com.net.xpay.core.model.AdminChargeModel;
import com.net.xpay.core.model.CancelChargeRecordModel;
import com.net.xpay.core.model.ChargeRecordSearchModel;
import com.net.xpay.core.service.ChargeService;
import com.net.xpay.core.utils.BeanCopierUtil;
import com.net.xpay.core.utils.JxlsUtils;
import com.net.shard.ShardUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *

 * 读取从commonChargeRecord中读，commonChargeRecord是分库聚合表
 */
@Slf4j
@RestController
@RequestMapping("/admin/charge-record")
@Api(tags = "运营/商户充值", description = "运营 商户充值 net")
public class AdminChargeRecordController {

    @Autowired
    private ChargeService chargeService;

    @Autowired
    private UserShardManager userShardManager;

    @Autowired
    private CommonChargeRecordManager commonChargeRecordManager;

    @ApiOperation("运营充值")
    @PostMapping("/charge-by-admin")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'charge-record::charge-by-admin')")
    @OperateLog(methodType = MethodType.INSERT, methodDesc = "运营充值",module = FunctionModule.ADMIN_CHARGE)
    public ResultData<ChargeRecord> chargeByAdmin(@RequestBody AdminChargeModel chargeModel) {
        Preconditions.checkArgument(chargeModel.getUserId() != null);
        UserShard userShard = userShardManager.getById(chargeModel.getUserId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            return new ResultData<>(chargeService.doChargeByAdmin(chargeModel));
        } finally {
            ShardUtil.cleanShardContext();
        }

    }

    @ApiOperation("运营充值体验次数")
    @PostMapping("/charge-trans-batch-by-admin")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'charge-record::charge-trans-batch-by-admin')")
    public ResultData<Boolean> chargeTransBatchByAdmin(@RequestBody AdminChargeModel chargeModel) {
        Preconditions.checkArgument(chargeModel.getUserId() != null);
        UserShard userShard = userShardManager.getById(chargeModel.getUserId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            chargeService.doChargeTransBatchByAdmin(chargeModel);
            return new ResultData<>(true);
        } finally {
            ShardUtil.cleanShardContext();
        }

    }



    @ApiOperation("搜索充值记录")
    @PostMapping("/search")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'charge-record::search')")
    public ResultPagedList<CommonChargeRecord> searchChargeRecord(@RequestBody ChargeRecordSearchModel searchModel) {
        List<CommonChargeRecord> records = commonChargeRecordManager.search(searchModel);
        long count = commonChargeRecordManager.searchCount(searchModel);

        long successAmount = commonChargeRecordManager.sumSuccessAmount(searchModel.getUserId(),searchModel.getEndMinTime(),searchModel.getEndMaxTime());
        ResultPagedList<CommonChargeRecord> ret = new ResultPagedList<>(records, count, searchModel);
        ret.setExtra(new BigDecimal(successAmount).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP).toString());
        return ret;
    }

    @ApiOperation("搜索单个充值记录")
    @GetMapping
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'charge-record::get')")
    public ResultData<CommonChargeRecord> getChargeRecord(Long id) {
        CommonChargeRecord commonChargeRecord = commonChargeRecordManager.getById(id);


        return new ResultData<>(commonChargeRecord);
    }

    /**
     * 作废充值记录
     */
    @ApiOperation("作废充值记录")
    @PostMapping("/cancel-charge-record")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'charge-record::cancel-charge-record')")
    @OperateLog(methodType = MethodType.INSERT, methodDesc = "作废充值记录",module = FunctionModule.ADMIN_CHARGE)
    public ResultData<Boolean> cancelChargeRecord(@RequestBody CancelChargeRecordModel model) {
        UserShard userShard = userShardManager.getById(model.getUserId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            chargeService.cancelChargeRecord(model);
        } finally {
            ShardUtil.cleanShardContext();
        }
        return new ResultData<>(true);
    }

    /**
     * 充值记录记录导出
     */
    @ApiOperation("充值记录记录导出")
    @GetMapping("/export")
    public ResultData<Boolean> exportChargeRecord(@ApiIgnore HttpServletRequest request, @ApiIgnore HttpServletResponse response, String searchModelJson) {
        Preconditions.checkArgument(searchModelJson != null);

        ChargeRecordSearchModel searchModel = SerializationUtil.str2Object(searchModelJson, ChargeRecordSearchModel.class);
        long count = commonChargeRecordManager.searchCount(searchModel);
        if (count >= 10000L){
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "记录超过10000条，无法导出");
        }
        List<CommonChargeRecord> userTransStatList = commonChargeRecordManager.list(searchModel);
        List<ChargeRecordExportVo> vos = BeanCopierUtil.batchCopy(CommonChargeRecord.class, ChargeRecordExportVo.class,userTransStatList );
        for (ChargeRecordExportVo vo : vos) {
            vo.setShowAmount(new BigDecimal(vo.getAmount().toString()).multiply(new BigDecimal("0.01")).setScale(2, RoundingMode.HALF_UP));
        }


        // 定义一个Map，往里面放入要在模板中显示数据
        Map<String, Object> model = new HashMap<>();

        model.put("records", vos);

        String fileName = "充值记录.xlsx";
        String template = "/excel/tpl/充值记录.xls";

        InputStream is;
        try {
            //获取模板流
            is = getClass().getResourceAsStream(template);

            //火狐游览器中文文件名会有乱码,兼容火狐
            String agent = request.getHeader("USER-AGENT").toLowerCase();

            if (!Strings.isNullOrEmpty(agent) && (agent.contains("firefox") || agent.contains("safari"))) {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            }
            response.setContentType("application/force-download");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            JxlsUtils.exportExcel(is, response.getOutputStream(), model);
            response.flushBuffer();
        } catch (IOException e) {
            log.warn("export error", e);
        }
        return new ResultData<>();
    }
}
